import javax.vecmath.*;

/**
 * @author Eric Muehlberg
 *
 *	Collision checking only perhaps?
 */
public class Cube
{
	//Center point
	Point3f pos;
	
	Orientation o;

	/*
	//Top
	Point3f tpv1, tpv2, tpv3, tpv4;
	//Bottom
	Point3f btv1, btv2, btv3, btv4;
	//Left
	Point3f lv1, lv2, lv3, lv4;
	//Right
	Point3f rv1, rv2, rv3, rv4;
	//Front
	Point3f fv1, fv2, fv3, fv4;
	//Back
	Point3f bkv1, bkv2, bkv3, bkv4;
	*/
	//dimensions
	float w, h, d;
	
	//x,y,z are the coords of the center point
	public Cube(float x, float y, float z, float w, float h, float d)
	{
		
		pos = new Point3f(x,y,z);
		this.w = w;
		this.h = h;
		this.d = d;
		
		o = Orientation.xAxis;
		//initverts();
	}
	
	/**
	 * Returns relative X coord
	 * @return
	 */
	public float getRX()
	{
		if(o == Orientation.xAxis)
			return pos.x;
		else if( o == Orientation.nxAxis)
			return -pos.x;
		else if(o == Orientation.zAxis)
			return -pos.z;

		else if(o == Orientation.nzAxis)
			return pos.z;
		else
			return 0;
	}
	public float getRZ()
	{
		
		if(o == Orientation.xAxis)
			return pos.z;
		else if( o == Orientation.nxAxis)
			return -pos.z;
		else if(o == Orientation.zAxis)
			return pos.x;

		else if(o == Orientation.nzAxis)
			return -pos.x;
		else
			return 0;
	}
	public float getX()
	{
		return pos.x;
	}
	
	/**
	 * Returns relative width
	 * @return
	 */
	public float getRW()
	{
		if(o == Orientation.xAxis || o == Orientation.nxAxis)
			return w;
		else if(o == Orientation.zAxis || o == Orientation.nzAxis)
			return d;
		else
			return 0;
	}
	
	public float getW()
	{
		return w;
	}
	
	public float getY()
	{
		return pos.y;
	}
	
	public float getZ()
	{
		return pos.z;
	}
	
	public float getH()
	{
		return h;
	}
	
	public float getD()
	{
		return d;
	}
	
	public Orientation getO()
	{
		return o;
	}
	
	public void updateX(float x)
	{
		if(o == Orientation.xAxis || o == Orientation.nxAxis)
		{
			pos.x += x;
		}
		else if(o == Orientation.zAxis || o == Orientation.nzAxis)
		{
			pos.z += x;
		}
	}
	public void updateRZ(float z)
	{
		if(o == Orientation.xAxis || o == Orientation.nxAxis)
		{
			pos.z = z;
		}
		else if(o == Orientation.zAxis || o == Orientation.nzAxis)
		{
			pos.x = z;
		}
		
	}
	public void updateY(float y)
	{
		pos.y += y;
	}
	
	/**
	 * Changes the characters orientation to the respective plane
	 * via a 90 degree rotation of the level to the left.
	 */
	public void snapleft()
	{
		switch(o)
		{
		case xAxis:
			o = Orientation.nzAxis;
			break;
		case nxAxis:
			o = Orientation.zAxis;
			break;
		case zAxis:
			o = Orientation.xAxis;
			break;
		case nzAxis:
			o = Orientation.nxAxis;
			break;
		}
	}
	
	/**
	 * Changes the characters orientation to the respective plane
	 * via a 90 degree rotation of the level to the right.
	 */
	public void snapright()
	{
		switch(o)
		{
		case xAxis:
			o = Orientation.zAxis;
			break;
		case nxAxis:
			o = Orientation.nzAxis;
			break;
		case zAxis:
			o = Orientation.nxAxis;
			break;
		case nzAxis:
			o = Orientation.xAxis;
			break;
		}
	}
	
	/*collides takes in a face of a box that possibly collides with the obj and any face of that obj
	 * if the distance from any of the faces of "of" are closer to the center of the obj there is a collision.
	 * 
	 * @param of: face of collision check
	 * @param of2: any face of obj
	 * @param obj: WObject to check for collision.
	 */
	/*
	public boolean collides(ObjectFace of, ObjectFace of2, WObject obj)
	{
		//distance from the face of this object to the other objects center
		float corner1dist = computeSSQ(of.bottoml.x, obj.x, of.bottoml.y, obj.y, of.bottoml.z, obj.z);
		float corner2dist = computeSSQ(of.bottomr.x, obj.x, of.bottomr.y, obj.y, of.bottomr.z, obj.z);
		float corner3dist = computeSSQ(of.topl.x, obj.x, of.topl.y, obj.y, of.topl.z, obj.z);
		float corner4dist = computeSSQ(of.topr.x, obj.x, of.topr.y, obj.y, of.topr.z, obj.z);
		
		//System.out.print("magnitudes c1, c2, c3, c4: ");
		//System.out.println(corner1dist + "\t" + corner2dist + "\t" + corner3dist + "\t" + corner4dist + "\t");
		
		//distance from the face of the other object to the other objects center	
		float magOfOtherCorners = computeSSQ(of2.bottoml.x, obj.x, of2.bottoml.y, obj.y, of2.bottoml.z, obj.z);
		
		//System.out.println(magOfOtherCorners);
		
		if(Math.abs(this.pos.y - obj.y) >= 1 )
			return false;
		if(Math.abs(this.pos.x - obj.x) >= 1 )
			return false;
		if(Math.abs(this.pos.z - obj.z) >= 1 )
			return false;
		//if the distance from any of the corners on the moving cube is closer to the center of the other box then
		// the distance to the outer most edge of that cube there is a collision.
		if(magOfOtherCorners > corner1dist || magOfOtherCorners > corner2dist || 
				magOfOtherCorners > corner3dist || magOfOtherCorners > corner4dist)
			return true;
		
		return false;
	}
	
	
	
	private float computeSSQ(float x1, float x2, float y1, float y2, float z1, float z2)
	{
		float returnValue = (float) Math.sqrt(((x1 - x2) * (x1 - x2)) +
				((y1 - y2) * (y1 - y2)) +
				((z1 - z2) * (z1 - z2)));
		return returnValue;
	}
	
	//start position changes
	public void decreaseX(float amount) {
		pos.x -= amount;
		
	}

	public void increaseZ(float amount) {
		pos.z += amount;
		
	}

	public void increaseX(float  amount) {
		pos.x +=  amount;
		
	}

	public void decreaseZ(float  amount) {
		pos.z +=  amount;
		
	}
	//end position changes
	
	
	/* these methods return faces dynamically based of the x,y,z position, pos, of the cube.
	 * start getters
	 */
	
	public ObjectFace getBottom()
	{
		return  new ObjectFace(this.pos.x-2/w, this.pos.x+w/2,  this.pos.y-h/2, this.pos.y-h/2, this.pos.z+d/2, this.pos.z-d/2);
	}
	public ObjectFace getTop()
	{
		return   new ObjectFace(this.pos.x-2/w, this.pos.x+w/2,  this.pos.y+h/2, this.pos.y+h/2, this.pos.z+d/2, this.pos.z-d/2);
	}
	public ObjectFace getLeft()
	{
		return  new ObjectFace(this.pos.x-2/w, this.pos.x-w/2,  this.pos.y-h/2, this.pos.y+h/2, this.pos.z+d/2, this.pos.z-d/2);
	}
	public ObjectFace getRight()
	{
		return new ObjectFace(this.pos.x+2/w, this.pos.x+w/2,  this.pos.y-h/2, this.pos.y+h/2, this.pos.z+d/2, this.pos.z-d/2);
	}
	public ObjectFace getFront()
	{
		return  new ObjectFace(this.pos.x-2/w, this.pos.x+w/2,  this.pos.y-h/2, this.pos.y+h/2, this.pos.z+d/2, this.pos.z+d/2);
	}
	public ObjectFace getBack()
	{
		return  new ObjectFace(this.pos.x-2/w, this.pos.x+w/2,  this.pos.y-h/2, this.pos.y+h/2, this.pos.z-d/2, this.pos.z-d/2);
	}
	// End getters
	
/*
	public void initverts()
	{
		tpv1 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z + d/2));
		tpv2 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z - d/2));
		tpv3 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z + d/2));
		tpv4 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z - d/2));

		btv1 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z + d/2));
		btv2 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z - d/2));
		btv3 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z + d/2));
		btv4 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z - d/2));
		
		lv1 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z - d/2));
		lv2 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z + d/2));
		lv3 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z - d/2));
		lv4 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z + d/2));
		
		rv1 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z + d/2));
		rv2 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z - d/2));
		rv3 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z + d/2));
		rv4 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z - d/2));
		
		fv1 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z + d/2));
		fv2 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z + d/2));
		fv3 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z + d/2));
		fv4 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z + d/2));
		
		bkv1 = new Point3f((pos.x + w/2),(pos.y + h/2), (pos.z - d/2));
		bkv2 = new Point3f((pos.x - w/2),(pos.y + h/2), (pos.z - d/2));
		bkv3 = new Point3f((pos.x + w/2),(pos.y - h/2), (pos.z - d/2));
		bkv4 = new Point3f((pos.x - w/2),(pos.y - h/2), (pos.z - d/2));
	}
	*/
}
